test(evm): migrate lib.js tx helpers from -b block to -b sync (CON-256)#3363
Open
wen-coding wants to merge 20 commits into
Open
test(evm): migrate lib.js tx helpers from -b block to -b sync (CON-256)#3363wen-coding wants to merge 20 commits into
wen-coding wants to merge 20 commits into
Conversation
bankSend, fundSeiAddress, executeWasm, associateWasm all used -b block (broadcast-mode block), which subscribes to tendermint's EventDataTx for the submitted hash and waits up to 60s for it to fire. Under Autobahn the executeBlock path doesn't invoke FireEvents, so EventDataTx is never published and -b block hangs to the timeout, blocking every test that funds an account or runs a wasm message in beforeEach / before-all hooks. Switch to -b sync (returns on mempool acceptance) plus a fixed 2s sleep to let inclusion happen. Portable across both engines: under CometBFT this is slightly slower than the event-driven detection -b block had, but the difference is in the noise of the surrounding hardhat-ethers polling. Under Autobahn it unblocks the test paths entirely. Verified locally: EVMPrecompileTest's Bank, Addr, Distribution, Staking, Oracle precompile sections (which depend on getAdmin → fundSeiAddress) go from 0/all hung in before-all to 9/9 passing. Gov + Wasm precompile sections still fail because they have direct -b block calls inside the test files themselves; those need separate substitutions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
Same migration as the prior commit, extended to two more sites that don't read post-execution event data: - associateKey: result is unused (wrapped in try/catch swallowing all errors). The -b block timeout was a 60s wait under Autobahn before the catch fired. - passProposal gov vote: caller polls proposal status afterward; the vote-tx return value is unused. Helpers that parse post-execution events from the response (storeWasm, proposeParamChange, registerPointerForERC*, etc.) stay on -b block in this PR — they need a separate "submit then poll for tx result" change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI on this PR caught a regression: CW1155toERC1155PointerTest's "should not transfer an NFT if not owned" reads res.code from executeWasm and expects it to be non-zero (the wasm execution should fail when the sender doesn't own the tokens). Under -b block, res.code is the DeliverTx code (post-execution); under -b sync it's the CheckTx code (mempool acceptance). For a tx that passes basic checks but fails in DeliverTx, -b sync returns 0 and the test wrongly thinks the tx succeeded. executeWasm and associateWasm have callers that read post-execution fields (code, events, logs) from the response, so they can't migrate to the -b sync pattern without also adding a "submit then poll for tx result" step. Revert these two; leave the truly response-agnostic helpers (bankSend, fundSeiAddress, associateKey, passProposal vote) on -b sync. The complex helpers are deferred to the same follow-up PR that addresses storeWasm, proposeParamChange, and the other event-parsing callers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reviewer flagged the magic 2s sleep after -b sync submissions: under CometBFT (block ~1s) it's marginal; under Autobahn (block ~100ms) it's 20x longer than needed. Both are arbitrary. Replace with waitForBlocks(1): poll eth_blockNumber every 50ms until the chain advances by one block, with a 15s timeout. Engine-agnostic substitute that returns as soon as the next block lands. Net wall-clock impact (Bank/Addr/Distribution precompile sections): - CometBFT: 19s → 15s - Autobahn: 39s → 10s Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI on this PR caught a sequence mismatch in SeiSoloTest's "Claim CW20 Tester / before all": fundSeiAddress submits with -b sync and waitForBlocks(1) returns when the next block lands. That next block can be empty (the submitted tx is still in mempool and lands one block later), so the chain hasn't advanced the funder's account sequence yet. The follow-up storeWasm queries the funder's account, gets the stale sequence, signs with it, and is rejected when the funder tx finally lands a block later and bumps the sequence. Default to 2 blocks instead of 1: closes the empty-next-block race without reintroducing a fixed sleep. Callers no longer pass an explicit block count — the helper takes care of the safety margin. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3363 +/- ##
==========================================
- Coverage 59.27% 59.13% -0.14%
==========================================
Files 2114 2097 -17
Lines 175221 171838 -3383
==========================================
- Hits 103864 101622 -2242
+ Misses 62311 61399 -912
+ Partials 9046 8817 -229
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Two more lib.js helpers were still using --broadcast-mode=block. Under
Autobahn the executeBlock path doesn't fire EventDataTx, so -b block
hangs to its 60s timeout on every call.
evmSend (used by fundAddress, called from setupSigners and many test
file before-hooks): convert to -b sync + waitForBlocks. Callers read
only the txhash from the output, which is present in either format,
so no other adjustment needed. This unblocks EVMPrecompileTest and
EVMGigaTest's `transfer to non-existent contract with data` (latter
verified passing in 126ms after the fix).
proposeParamChange: convert to -b sync. The tx response under -b sync
no longer carries deliver_tx events, so we can't read proposal_id from
the submit_proposal event. Poll gov state instead (max-id-before vs
max-id-after) — autobahn doesn't run a Cosmos-side tx indexer so
seid q tx <hash> isn't an option. New maxProposalId helper handles the
"no proposals exist yet" case explicitly via try/catch; using a shell
`|| echo '{...}'` fallback breaks because the docker-exec wrapper
double-quotes the inner command. Verified by EVMCompatabilityTest
test #3 (`should reproduce mismatch by changing param`) passing in
47s after the fix (was timing out at 120s with -b block).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Last lib.js helper still using --broadcast-mode=block. Same Autobahn incompatibility as evmSend / proposeParamChange: executeBlock doesn't fire EventDataTx, so -b block hangs to its 60s timeout on every call, which blocked ERC20toNativePointerTest's before-all hook. The original code read the new denom from the create_denom event in the tx response. Under -b sync we don't get deliver_tx events, but the tokenfactory denom is deterministic — `factory/<creator>/<subdenom>` where creator is the bech32 of the --from key. Construct it locally from getKeySeiAddress instead. Verified: ERC20toNativePointerTest passes 14/14 in 17s after the fix (previously 0/1, hung 60s+ on the before-all hook). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Gov Precompile section's before-hook had its own inline 'seid tx gov submit-proposal param-change ... -b block' which hangs 60s under Autobahn. Replace with the lib.js proposeParamChange helper (now -b sync + poll gov state). EVMPrecompileTest goes from 9/11 to 10/11 — only the Wasm Precompile section still fails (out of scope; wasm being decommed). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
wen-coding
added a commit
that referenced
this pull request
May 7, 2026
…y scripts Builds on the previous commit (submitAndWaitForTx + storeWasm + registerPointerForERC20 worked examples) and finishes the response- reading-helper migration that #3363 deferred. Migrated in contracts/test/lib.js: - storeWasm (already done in prior commit) - registerPointerForERC20 (already done in prior commit) - registerPointerForERC721 NEW - registerPointerForERC1155 NEW - executeWasm NEW (the one #3363 had to revert) - associateWasm NEW - proposeCW20toERC20Upgrade NEW - instantiateWasm NEW - deployErc20PointerForCw20 NEW (-b block -> -b sync; existing EVM-receipt poll handles wait) - deployErc20PointerNative NEW (same) - deployErc721PointerForCw721 NEW (same) - deployErc1155PointerForCw1155 NEW (same) New shared bash helper: integration_test/contracts/_tx_helpers.sh Defines submit_and_wait_for_tx() — bash equivalent of the JS helper. Reads the broadcast response from stdin (must use --broadcast-mode=sync), polls `seid query tx <hash>` until included, prints the tx response. Migrated deploy scripts in integration_test/contracts/: - deploy_wasm_contracts.sh (3 store + 3 instantiate calls) - create_tokenfactory_denoms.sh (3 create-denom calls) - deploy_dex_contract.sh (store + instantiate + register-contract + 4 register-pairs) - deploy_timelocked_token_contract.sh (7 bank-sends + 2 store + 2 instantiate) Out of scope (separate effort): - yaml-based cosmos integration tests (gov, oracle, authz, staking, bank, distribution, mint) — these use -b block in shell commands parsed by integration_test/scripts/runner.py. Migrating needs runner.py support for the submit-then-poll pattern. - Helpers already migrated in #3363 (evmSend, bankSend, fundSeiAddress, associateKey, createTokenFactoryTokenAndMint, proposeParamChange, passProposal vote) — left unchanged here to avoid conflicts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Strip comments that described the old -b block behavior or contrasted -b sync against it. Reader of the current code doesn't need to know what was replaced; comments now describe pure invariants (empty-next-block race, deterministic denom format, diff-against-snapshot proposal identification, seid's empty-gov-set exit code). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Read title/description/changes/is_expedited from the JSON file directly rather than duplicating them inline. deposit/fees stay inline (they're not part of the proposal spec; they're CLI-level args). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…aramChange After polling identifies the new proposal id, fetch the proposal and assert its title matches what we submitted. Closes the sharp edge where a concurrent submission (or DeliverTx silent failure followed by an unrelated submission) would otherwise cause us to return someone else's id. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Keep original command/mint_command/send_command variable names and inline-execute pattern. Only changes vs main are: derive token_denom locally instead of from the create_denom event, swap -b block for -b sync, and waitForBlocks between submissions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- createTokenFactoryTokenAndMint: check response.code on each sync submit; previously a CheckTx rejection would silently leave the function with a non-existent denom. Now matches proposeParamChange's pattern. - Drop redundant `await delay()` after helpers that already do waitForBlocks internally (fundAddress, getNativeAccount, setupSigners loop). The delay was carrying inclusion-wait duties; waitForBlocks inside the helper supersedes it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d5196a6. Configure here.
If multiple proposals land in one polling interval (250ms), the loop must scan every id in (maxIdBefore, cur] to find ours by title — not just the max. Otherwise we'd throw on a title mismatch against a concurrent submission's proposal even when ours did land. Also keep polling (rather than erroring) if none of the new ids match our title; the 30s deadline catches the genuine "ours never landed" case. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Several helpers in
contracts/test/lib.jsused-b block, which subscribes toEventDataTxserver-side. Under Autobahn theexecuteBlockpath doesn't fire those events, so-b blockdeterministically times out at 60s. Sei's vendored cosmos-sdk already advises against it (sei-cosmos/client/broadcast.go: "use BroadcastTxAsync or BroadcastTxSync instead").Migrated to
-b sync(with newwaitForBlocks(blocks=2)helper between submissions):evmSend,bankSend,fundSeiAddress,associateKey,passProposalvote — callers don't need the deliver_tx response.createTokenFactoryTokenAndMint— derives the denom locally asfactory/<creator>/<subdenom>instead of reading thecreate_denomevent.proposeParamChange— pollsmaxProposalId()and asserts the new proposal's title matches what we submitted (catches concurrent submission / DeliverTx silent failure).EVMPrecompileTest.jsGov before-hook — replaced an inlineseid tx ... -b blockwith the lib.js helper; reads the spec fromparam_change_proposal.jsondirectly.Verification
before allAlso unblocked under Autobahn:
EVMPrecompileTestGov (10/11 passing — Wasm out of scope),ERC20toNativePointerTest(14/14 in 17s),EVMCompatabilityTestparam-change test (47s, was timing out at 120s).Note
Medium Risk
Moderate risk because it changes how integration tests submit and observe on-chain transactions (broadcast mode, timing/polling), which could introduce new race conditions or longer waits if block production differs in CI.
Overview
Moves multiple
contracts/test/lib.jsCLI tx helpers from-b blockto-b sync, addingwaitForBlocks()to explicitly wait for chain progress after submits instead of relying on deliver-tx/event subscriptions.Hardens higher-level helpers:
createTokenFactoryTokenAndMint()now derives the tokenfactory denom deterministically and checks JSONcodeerrors;proposeParamChange()now discovers the new proposal by polling gov state (maxProposalId()+ title match) rather than parsing submit events;passProposal()votes via-b sync.Updates
EVMPrecompileTest.jsto use the sharedproposeParamChange()helper (loadingparam_change_proposal.json) instead of inlining aseid tx gov submit-proposal ... -b blockcall.Reviewed by Cursor Bugbot for commit fd84af4. Bugbot is set up for automated code reviews on this repo. Configure here.